using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using Promike.site.Models;

namespace Promike.site.Models
{ 
    public class PhotoRepository : IPhotoRepository
    {
        readonly PromikeContext context = new PromikeContext();

        public IQueryable<Photo> All
        {
            get { return context.Photos; }
        }

        public IQueryable<Photo> AllIncluding(params Expression<Func<Photo, object>>[] includeProperties)
        {
            IQueryable<Photo> query = context.Photos;
            foreach (var includeProperty in includeProperties) {
                query = query.Include(includeProperty);
            }
            return query;
        }

        public Photo Find(int id)
        {
            return context.Photos.Find(id);
        }

        public void InsertOrUpdate(Photo photo)
        {
            if (photo.Id == default(int)) {
                // New entity
                context.Photos.Add(photo);
            } else {
                // Existing entity
                context.Entry(photo).State = EntityState.Modified;
            }
        }

        public void Delete(int id)
        {
            var photo = context.Photos.Find(id);
            context.Photos.Remove(photo);
        }

        public void Save()
        {
            context.SaveChanges();
        }

        public void AddClick(Photo model)
        {
            if (model != null)
            {
                model.Clicks = model.Clicks + 1;
                if (model.Id == default(int))
                {
                    // New entity
                    context.Photos.Add(model);
                }
                else
                {
                    // Existing entity
                    context.Entry(model).State = EntityState.Modified;
                }
                context.SaveChanges();
            }
        }

        public decimal GetAllCount()
        {
            var model = context.Photos;
            return model.Count();
        }

        public Photo FindPrev(int id)
        {
            var ids = context.Photos.OrderBy(p=>p.Id).Select(p=>p.Id).ToArray();
            var index = 0;
            foreach (var i in ids)
            {
                if (i == id)
                {
                    return context.Photos.Find(index == 0 ? id : ids[index-1]);
                }
                index++;
            }
            return context.Photos.Find(id);
        }

        public Photo FindNext(int id)
        {
            var ids = context.Photos.OrderBy(p => p.Id).Select(p => p.Id).ToArray();
            var index = 0;
            foreach (var i in ids)
            {
                if (i == id)
                {
                    return context.Photos.Find(index == ids.Length-1 ? id : ids[index + 1]);
                }
                index++;
            }
            return context.Photos.Find(id);
        }

        public List<Photo> GetFilteredPhoto(int? filterType)
        {
            return filterType == null ? context.Photos.ToList() : context.Photos.Where(p => p.Album == filterType).ToList();
        }

        public Photo FindByName(string id)
        {
            return context.Photos.FirstOrDefault(p=>p.FileName == id);
        }

        public List<Photo> GetAllVisibleCycle()
        {
            return
                context.Photos.Where(p => p.Cycle == true && p.Visible == true)
                       .OrderByDescending(p => p.DatePublish)
                       .ToList();
        }

        public void Dispose() 
        {
            context.Dispose();
        }
    }

    public interface IPhotoRepository : IDisposable
    {
        IQueryable<Photo> All { get; }
        IQueryable<Photo> AllIncluding(params Expression<Func<Photo, object>>[] includeProperties);
        Photo Find(int id);
        void InsertOrUpdate(Photo photo);
        void Delete(int id);
        void Save();
        void AddClick(Photo model);
        decimal GetAllCount();
        Photo FindPrev(int id);
        Photo FindNext(int id);
        List<Photo> GetFilteredPhoto(int? filterType);
        Photo FindByName(string id);
        List<Photo> GetAllVisibleCycle();
    }
}